#ifndef COMB_IO_HPP__
#define COMB_IO_HPP__

#include <iostream>
#include <fstream>

#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>

#include <boost/serialization/base_object.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/valarray.hpp>

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/gzip.hpp>

#include "boost/multi_array.hpp"

#include "comb_types.hpp"

/** 
 * Read snp calls from a file.
 * \param fname the filename to load from
 * \param diploid true if we are in diploid case
 * \param cv the snp call data structure to populate.
 */
void read_col_snp_call_file(const char *fname, bool &diploid, color_call_vector_t &cv);

/** Read snp calls from an input stream.
 * \param is the input stream to read from.
 * \param diploid true if we are in diploid case
 * \param cv the snp call data structure to populate.
 */
void read_col_snp_call(std::istream &is, bool &diploid, color_call_vector_t &cv);

/** Read the sequence space SNPs into the call vector. 
 * \param fname the name of the file to read.
 * \param diploid true if calling diploid
 * \param cv the seq_call_vector_t to populate from the file.
 */
void read_seq_snp_call_file(const char *fname, bool &diploid, seq_call_vector_t &cv);

/** Read the sequence calls in from a stream.
 * \param is the stream to read.
 * \param diploid true if calling diploid.
 * \param cv the seq_call_vector_t to populate from the file.
 */
void read_seq_snp_call(std::istream &is, bool &diploid, seq_call_vector_t &cv);

/** Write the contents of the color snp call information to a stream.
 * \param os the output stream to write to.
 * \param diploid true if calling diploid.
 * \param cv the data to write.
 */
void write_col_snp_call(std::ostream &os, bool diploid, color_call_vector_t &cv);

/** Write the contents of the color snp call information to a stream.
 * \param os the output stream to write to.
 * \param diploid true if calling diploid.
 * \param cv the data to write.
 */
void write_seq_snp_call(std::ostream &os, bool diploid, seq_call_vector_t &cv);

/** Dump expression information to a stream.
 * \param os the output stream to write to.
 * \param expression the expression data to write.
 */
void write_expression(std::ostream &os, map_str_vafl_t &expression);

/** Write color space call rates data to a stream.
 * \param os the output stream to write to.
 * \param calls the call rates matrix to write.
 */
void write_call_counts(std::ostream &os, array_type5 &calls);

/** Write color space call rates data to a file.
 * \param fname the file to write to.
 * \param calls the call rates matrix to write.
 */
void write_call_counts_file(char *fname, array_type5 &calls);

/** Read color space call rates data from a stream.
 * \param is the input stream to read from.
 * \param calls the call rates matrix to read.
 */
void read_call_counts(std::istream &is, array_type5 &calls);


/** Read color space call counts data from a file.
 * \param fname the file to read from
 * \param calls the call rates matrix to read.
 */
void read_call_counts_file(const char *fname, array_type5 &calls);

/** Read color space snp candidates
 * \param is input stream to read from
 * \param cand_blocks the SNP candidate structure to be populated.
 * \param snp_cands the SNP candidate structure to be populated.
 */
void read_snp_cand(std::istream &is, cand_blocks_t &cand_blocks, cand_vector_t &snp_cands);

/** Read color space snp candidates
 * \param fname the file name to read from
 * \param cand_blocks the SNP candidate structure to be populated.
 * \param snp_cands the SNP candidate structure to be populated.
 */
void read_snp_cand_file(const char *fname, cand_blocks_t &cand_blocks, cand_vector_t &snp_cands);

/** Write the snp candidates to a stream,
 * \param os the output stream to write to.
 * \param cand_blocks the SNPs to write out.
 * \param snp_cands the SNPs to write out.
 */
void write_snp_cand(std::ostream &os, cand_blocks_t &cand_blocks, cand_vector_t &snp_cands);

/** Read the map count information from a file.
 * \param fname the file to read.
 * \param subs the count data to be populated.
 * \param totl the count data to be populated.
 */
void read_map_count_file(const char *fname, mapping_type &t, map_str_vafl_t &subs, map_str_vafl_t &totl);


/** Read the map count information from a stream.
 * \param is the stream to read from.
 * \param subs the count data to be populated.
 * \param totl the count data to be populated.
 */
void read_map_count(std::istream &is, mapping_type &t, map_str_vafl_t &subs, map_str_vafl_t &totl);

/** Write the map count information to a stream.
 * \param os the stream to write to.
 * \param subs the count data to be written.
 * \param totl the count data to be written.
 */
void write_map_count(std::ostream &os, mapping_type &t, map_str_vafl_t &subs, map_str_vafl_t &totl);

/** Write sequence space call counts to a stream.
 * \param os the stream to write to
 * \param calls the call count matrix to write.
 */
void write_seq_call_counts(std::ostream &os, array_type4 &calls);

/** Write sequence space call counts to a file.
 * \param fname the filename to write to
 * \param calls the call count matrix to write.
 */
void write_seq_call_counts_file(char *fname, array_type4 &calls);

/** Read the sequence space call rates from a stream
 * \param is the stream to read from.
 * \param calls the call rates to populate.
 */
void read_seq_call_counts(std::istream &is, array_type4 &calls);

/** Read the sequence space call rates from a file
 * \param fname the file name to read from.
 * \param calls the call rates to populate.
 */
void read_seq_call_counts_file(const char *fname, array_type4 &calls);

#endif
